package convertTestsToJUnit;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import operations.CreateObject;
import operations.InvokeMethod;
import operations.Operation;
import operations.OperationResult;

import executor.ReflectionExecutor;

import ga.GAInfo;
import ga.Individual;
public class Splitter {
	public static List<Individual> split(final GAInfo gaInfo,final Individual test) {
		Splitter splitter = new Splitter();
		final List<Individual> res = new ArrayList<Individual>();

		res.addAll(splitter.analyze(gaInfo,test));
		res.add(test);

		return res;
	}
	private List<Individual>   analyze(final GAInfo gaInfo,final Individual originalTest) {
		List<Individual> listIndviduals = new ArrayList<Individual>();
		List<Operation> sucessfulOps = new ArrayList<Operation>();
		List<Operation> postconditionOps = new ArrayList<Operation>();
		List<Operation> partTest = new ArrayList<Operation>();

		for (Operation op : originalTest.getStatements()) {
			partTest.add(op);
	//		Individual tc=new Individual(originalTest.getInitialConstructors(), partTest);
	//		ReflectionExecutor.execute(gaInfo,tc);
	//		for (Operation op : tc.getStatements()) {

			OperationResult info = (OperationResult) op.getInfo(OperationResult.KEY);
			if(info != null) {
				switch(info.getStatus()) {
				case NOT_EXECUTED: // skip invalid & not executed operations
					break;
				case PRECONDITION_ERROR:
					List<Operation> PreConditionError = new ArrayList<Operation>(partTest);
						listIndviduals.add(new Individual(originalTest.getInitialConstructors(),PreConditionError));
					break;

				case POSTCONDITION_ERROR: // trigger a reset after a postcondition error
					postconditionOps.add(op);
//					ops.add(ResetRepository.singleton);
					break;

				case SUCCESSFUL: // add normal operations as-is
					sucessfulOps.add(op);
					break;

				case EXCEPTIONAL: // when an exception is thrown, the target is not set
					listIndviduals.add(new Individual(originalTest.getInitialConstructors(),sucessfulOps));
					break;
				}

			} else {
				if((op instanceof InvokeMethod || op instanceof CreateObject))
					System.err.println("split.analyze() An OperationResult is expected, but it is not found");

				sucessfulOps.add(op);
			}
		//	}
		}
		listIndviduals.add(new Individual(originalTest.getInitialConstructors(),sucessfulOps));
		return listIndviduals;
	}

}
